package com.itheima.app.manager;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.itheima.app.config.StringRedisConfig;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.Comment;
import com.itheima.domain.mongo.FocusUser;
import com.itheima.domain.mongo.Video;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.CommentService;
import com.itheima.service.mongo.FocusUserService;
import com.itheima.service.mongo.VideoService;
import com.itheima.util.ConstantUtil;
import com.itheima.vo.CommentVo;
import com.itheima.vo.PageBeanVo;
import com.itheima.vo.VideoVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Component
public class VideoManager {

    @DubboReference
    UserInfoService userInfoService;

    @DubboReference
    VideoService videoService;

    @Autowired
    FastFileStorageClient fastFileStorageClient;

    @Autowired
    FdfsWebServer fdfsWebServer;

    @DubboReference
    FocusUserService focusUserService;

    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @DubboReference
    private CommentService commentService;
    @Autowired
    private MQVideoManager mqVideoManager;
    @Autowired
    private StringRedisConfig stringRedisConfig;

    @Cacheable(value = "tanhua",key = "#userId+'_'+#pageNum+'_'+#pageSize",unless = "#result.counts==0")//用户id_页码_每页条数
    public PageBeanVo findRecommendVideoByPage(Long userId, Integer pageNum, Integer pageSize) {
        //1.远程调用service查询给我的视频
        PageBeanVo pageBeanVo = videoService.findRecommendVideoByPage(userId, pageNum, pageSize);

        //2.获取pageBeanVo中视频集合
        List<Video> videos = (List<Video>) pageBeanVo.getItems();

        //3.遍历视频集合,获取每个视频发布人userInfo,将视频和userInfo封装成VideoVo,将每个vo放入voList中
        List<VideoVo> voList = new ArrayList<>();

        if (CollUtil.isNotEmpty(videos)) {
            videos.forEach(video -> {
                UserInfo userInfo = userInfoService.findById(video.getUserId());

                //将视频和userInfo封装成VideoVo
                VideoVo vo = new VideoVo();

                //先封装userInfo后封装video
                vo.setUserInfo(userInfo);
                vo.setVideo(video);

                //判断用户是否关注
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.FOCUS_USER,userId,video.getUserId()))) {
                    vo.setHasFocus(1);
                }

                voList.add(vo);
            });
        }

        //4.将voList设置给pageBeanVo,返回pageBeanVo
        pageBeanVo.setItems(voList);
        return pageBeanVo;
    }

    //@CacheEvict(value = "tanhua",allEntries = true)//清除所有tanhua名称空间下所有缓存
    @CacheEvict(value = "tanhua",key = "#userId+'_*'")//清除所有tanhua名称空间下所有指定用户的缓存
    public ResponseEntity save(Long userId, MultipartFile videoThumbnail, MultipartFile videoFile) throws IOException {
        //查询redis中 看看是否有这个字段  如果有的话就返回提示
        if (stringRedisConfig.stringRedisTemplate2().hasKey("Free3"+UserHolder.get().getId())){
            return ResponseEntity.status(500).body("此用户处于冻结动态状态!");
        }
        //1.将封面保存到fastDFS,获取地址
        StorePath coverPath = fastFileStorageClient.uploadFile(
                videoThumbnail.getInputStream(),
                videoThumbnail.getSize(),
                FileUtil.extName(videoThumbnail.getOriginalFilename()),
                null);

        //2.将视频保存到fastDFS,获取地址
        StorePath videoPath = fastFileStorageClient.uploadFile(
                videoFile.getInputStream(),
                videoFile.getSize(),
                FileUtil.extName(videoFile.getOriginalFilename()),
                null);

        //3.封装video
        Video video = new Video();
        video.setCreated(System.currentTimeMillis());
        video.setUserId(userId);
        video.setText("高薪就业");
        video.setPicUrl(fdfsWebServer.getWebServerUrl()+coverPath.getFullPath());
        video.setVideoUrl(fdfsWebServer.getWebServerUrl()+videoPath.getFullPath());

        //4.远程调用service完成保存操作
        videoService.save(video);

        return ResponseEntity.ok(null);
    }

    public void userFocus(Long userId, Long focusUserId) {
        //1.封装focusUser
        FocusUser focusUser = new FocusUser();
        focusUser.setUserId(userId);
        focusUser.setFocusUserId(focusUserId);
        focusUser.setCreated(System.currentTimeMillis());

        //2.远程调用service完成保存
        focusUserService.save(focusUser);

        //3.保存用户关注的状态  focus_user:99_9
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.FOCUS_USER,userId,focusUserId),"1");
    }

    public void userUnFocus(Long userId, Long focusUserId) {
        focusUserService.delete(userId,focusUserId);
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.FOCUS_USER,userId,focusUserId));
    }



    /**
     * 视频点赞
     * @param videoId
     * @return
     */
    public ResponseEntity videoLike(ObjectId videoId) {
        // 1.获取当前用户的id
        Long userId = UserHolder.get().getId();
        // 2.根据id查询视频
        Video video = videoService.findById(videoId);
        // 3.封装comment对象
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());
        comment.setPublishId(videoId);
        comment.setCommentType(4);
        comment.setUserId(userId);
        comment.setPublishUserId(video.getUserId());
        // 4.远程调用service保存
        int count = commentService.save(comment);
        // 5.在redis中保存点赞标识
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.VIDEO_LIKE,userId,videoId),"1");
        // 将用户的操作保存mq
        mqVideoManager.sendVideo(userId,video.getId(),MQVideoManager.VIDEO_LIKE);
        // 6.返回最新点赞数量
        return ResponseEntity.ok(count);
    }

    /**
     * 视频取消点赞
     * @param videoId
     * @return
     */
    public ResponseEntity videoDislike(ObjectId videoId) {
        // 1.获取当前用户id
        Long userId = UserHolder.get().getId();
        // 2.远程调用
        int count = commentService.delete(userId, videoId, 4);
        // 3.删除点赞标识
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.VIDEO_LIKE,userId,videoId));

        //将操作放入mq
        mqVideoManager.sendVideo(userId,videoId,MQVideoManager.VIDEO_DISLIKE);
        return ResponseEntity.ok(count);
    }

    /**
     * 视频评论列表
     * @param videoId
     * @param pageNum
     * @param pageSize
     * @return
     */
    public ResponseEntity videoComments(ObjectId videoId, Integer pageNum, Integer pageSize) {
        // 1.远程调用 获取数据
        PageBeanVo pageBeanVo = commentService.findCommentByPage(videoId, pageNum, pageSize, 5);
        // 2.获取评论列表
        List<Comment> items = (List<Comment>) pageBeanVo.getItems();
        // 3.遍历 获取每个评论 获取评论发布人id 获取发布人userInfo 封装vo 将vo存list
        List<CommentVo> voList = new ArrayList<>();
        if (CollUtil.isNotEmpty(items)){
            for (Comment comment : items) {
                UserInfo userInfo = userInfoService.findById(comment.getUserId());


                CommentVo vo = new CommentVo();
                vo.setId(comment.getId().toString());
                vo.setAvatar(userInfo.getAvatar());
                vo.setNickname(userInfo.getNickname());
                vo.setContent(comment.getContent());
                vo.setCreateDate(DateUtil.formatDateTime(new Date(comment.getCreated())));


                voList.add(vo);
            }

        }
        // 4.将voList设置给pageBeanvo,将PageBeanVo返回
        pageBeanVo.setItems(voList);
        return ResponseEntity.ok(pageBeanVo);
    }

    /**
     * 发布视频评论
     * @param videoId
     * @return
     */
    public ResponseEntity videoComment(String videoId, Map<String,String> map) {
        // 判断用户是否被冻结
        if (stringRedisConfig.stringRedisTemplate2().hasKey("Free2"+ UserHolder.get().getId())) {
            return ResponseEntity.status(500).body("此用户处于冻结发言状态");
        }
        // 1.获取参数
        String content = map.get("comment");
        // 2.获取id
        Long userId = UserHolder.get().getId();
        // 3.获取视频详情
        Video video = videoService.findById(new ObjectId(videoId));
        // 4.封装comment
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());
        comment.setPublishId(new ObjectId(videoId));
        comment.setCommentType(5);
        comment.setUserId(userId);
        comment.setPublishUserId(video.getUserId());
        comment.setContent(content);

        // 5.远程调用service保存
        int count = commentService.save(comment);
        // 存入mq
        mqVideoManager.sendVideo(userId,video.getId(),MQVideoManager.VIDEO_COMMENT);
        // 6.返回最新数量
        return ResponseEntity.ok(count);
    }


}
